﻿using System.Collections;
using System.IO;
using System.Linq;
using System.Text;

namespace WenSkin
{
    public class Ini : ArrayList
    {
        public Ini()
        {
        }
        public Ini(string path)
        {
            Encoding = Encoding.UTF8;
            Path = path;
            Load(path);
        }
        public Ini(string path, Encoding encoding)
        {
            Path = path;
            Encoding = encoding;
            Load(path, encoding);
        }
        public new IniGroup this[int index] => base[index] as IniGroup;
        public IniItemCollection this[string str] => (base.ToArray().ToList().Find(a => (a as IniGroup).Name?.ToUpper() == str?.ToUpper()) as IniGroup)?.Items;
        public string this[string key, string name]
        {
            get => (base.ToArray().ToList().Find(a => (a as IniGroup).Name?.ToUpper() == key?.ToUpper()) as IniGroup)?.Items[name]?.Value;
            set
            {
                if (!(base.ToArray().ToList().Find(a => (a as IniGroup).Name?.ToUpper() == key?.ToUpper()) is IniGroup group))
                {
                    group = IniGroupItemAdd(key);
                }

                var item = group.Items[name];
                if (name == null || item == null)
                {
                    IniItemAdd(group, name, value);
                    return;
                }
                item.Value = value;
            }
        }

        #region 公有属性
        public string Path { get; private set; }
        public Encoding Encoding { get; private set; }
        public string Text
        {
            get
            {
                StringBuilder str = new StringBuilder();
                foreach (IniGroup group in this)
                {
                    if (!string.IsNullOrEmpty(group.Name))
                        str.Append($"[{group.Name}]\n");

                    foreach (IniItem item in group.Items)
                    {
                        switch (item.Name)
                        {
                            case null:
                                str.Append(item.Value + "\n");
                                break;
                            case "":
                                str.Append($"={item.Value}\n");
                                break;
                            default:
                                str.Append($"{item.Name}={item.Value}\n");
                                break;
                        }
                    }
                }
                var s = str.ToString();
                if (!string.IsNullOrEmpty(s) && s.ToString().EndsWith("\n"))
                {
                    s = s.Remove(s.Length - 1);
                }
                return s;
            }
        }
        #endregion

        public void Load(string path)
        {
            Load(path, Encoding.UTF8);
        }
        public void Load(string path, Encoding encoding)
        {
            Clear();
            if (!File.Exists(path))
                return;

            string[] texts = File.ReadAllLines(path, encoding);

            IniGroup group = null;
            foreach (var text in texts)
            {
                string t = text.Replace(" ", "");
                var idx = text.IndexOf("=");
                if (text.Replace(" ", "").StartsWith("[") && text.Replace(" ", "").EndsWith("]"))
                {

                    group = IniGroupItemAdd(text.Substring(text.IndexOf("[") + 1, text.IndexOf("]") - 1));
                }
                else if (t.StartsWith("!") || t.StartsWith(";") || t.StartsWith("]") || t.StartsWith("//") || string.IsNullOrEmpty(t))
                {
                    group = IniItemAdd(group, null, text);
                }
                else if (idx == -1)
                {
                    group = IniItemAdd(group, null, text);
                }
                else if (idx == 0)
                {
                    group = IniItemAdd(group, "", text);
                }
                else if (idx > 0)
                {
                    group = IniItemAdd(group, text.Substring(0, idx), text.Substring(idx + 1));
                }
            }
        }
        private IniGroup IniGroupItemAdd(string text)
        {
            IniGroup g = new IniGroup() { Name = text };
            Add(g);
            return g;
        }
        private IniGroup IniItemAdd(IniGroup group, string name, string value)
        {
            if (group == null)
            {
                group = IniGroupItemAdd("");
            }
            IniItem item = new IniItem()
            {
                Name = name,
                Value = value,
            };
            group.Items.Add(item);
            return group;
        }
        public void Save()
        {
            SaveAs(Path);
        }
        public void SaveAs(string path)
        {
            SaveAs(path, Encoding);
        }
        public void SaveAs(string path, Encoding encoding)
        {
            File.WriteAllText(path, Text, encoding);
        }
        public class IniItemCollection : ArrayList
        {
            public IniItemCollection()
            {
            }
            public new IniItem this[int index] => base[index] as IniItem;

            public IniItem this[string str] => base.ToArray().ToList().Find(a => (a as IniItem).Name?.ToUpper() == str?.ToUpper()) as IniItem;
        }
        public class IniGroup
        {
            private IniItemCollection items;
            public string Name { get; set; }
            public IniItemCollection Items => items ??= new IniItemCollection();
        }
        public class IniItem
        {
            public string Name { get; set; }
            public string Value { get; set; }
        }
    }
}
